package es.indra.druida.desktop.apps.drexplorer;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import java.util.ResourceBundle;
import es.indra.druida.desktop.configurator.ResourcesService;

/**
 * The Class DownloadFile.
 */
public class DownloadFile {

	/**
	 * Procesa download fichero.
	 * 
	 * @param userFileRelativePath
	 *            the user file relative path
	 * @param queryString
	 *            the query string
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * 
	 * @throws Exception
	 *             the exception
	 */
	public void procesaDownloadFichero (String userFileRelativePath, String queryString, HttpServletRequest request, HttpServletResponse response) throws Exception	{
		Boolean useThumbnail=false;		
		Boolean highQuality=false;
		if (queryString!=null)
			if (queryString.equals("thumbnail=true"))
				useThumbnail=true;
			else if (queryString.equals("thumbnail=hq")){
				useThumbnail=true;
				highQuality=true;
			}
		if (useThumbnail)	{
			if (userFileRelativePath==null){
				ResourceBundle bundle=ResourcesService.getResourceBundle("drExplorer",request);
				throw new Exception(bundle.getString("drExplorer.txt42"));
			}
			String[] piezas= userFileRelativePath.split("(/|\\\\)");
			String oFile=null;
			String oRuta=null;		
			if (piezas.length==0){
				oFile=userFileRelativePath;
				oRuta="";
			} else if (piezas.length>0)	{
				oFile=piezas[piezas.length-1];
				oRuta=userFileRelativePath.substring(0,userFileRelativePath.length()-(1+oFile.length()));
			}		
			HttpSession sesion=request.getSession();
			DrExplorerService explServ=new DrExplorerService();
			File fileToDownload = explServ.getFile(oRuta, oFile, sesion);
			BufferedImage image = ImageIO.read(fileToDownload);
			Map<Key, Object> map = new HashMap<Key, Object>();
			if (highQuality) {
				map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
				map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
				map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			} else {
				map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
				map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
				map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
			}
			RenderingHints hints = new RenderingHints(map);
			BufferedImage thumb=getThumbnail(image,94,90,hints);
			response.setContentType("image/jpeg");			
			ServletOutputStream out = response.getOutputStream();			
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam encodeParams = encoder.getDefaultJPEGEncodeParam(thumb);
		    encodeParams.setQuality(0.8F, false);
		    encoder.setJPEGEncodeParam(encodeParams);
		    encoder.encode(thumb);
		} else {
			procesaDownloadFichero ( userFileRelativePath, request, response );
		}
	}
	
	/**
	 * Procesa download fichero.
	 * 
	 * @param userFileRelativePath
	 *            the user file relative path
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * 
	 * @throws Exception
	 *             the exception
	 */
	public void procesaDownloadFichero (String userFileRelativePath, HttpServletRequest request, HttpServletResponse response) throws Exception	{
		if (userFileRelativePath==null){
			ResourceBundle bundle=ResourcesService.getResourceBundle("drExplorer",request);
			throw new Exception(bundle.getString("drExplorer.txt42"));			
		}
		String[] piezas= userFileRelativePath.split("(/|\\\\)");
		String oFile=null;
		String oRuta=null;		
		if (piezas.length==0){
			oFile=userFileRelativePath;
			oRuta="";
		} else if (piezas.length>0)	{
			oFile=piezas[piezas.length-1];
			oRuta=userFileRelativePath.substring(0,userFileRelativePath.length()-(1+oFile.length()));
		}		
		HttpSession sesion=request.getSession();
		DrExplorerService explServ=new DrExplorerService();
		File fileToDownload = explServ.getFile(oRuta, oFile, sesion);
		//System.out.println("attachment;filename="+fileToDownload.getName());
		response.setContentType("application/octet-stream");
		response.setHeader("Content-Disposition","attachment;filename="+fileToDownload.getName());
		//File file = new File("D:\\ECLIPSE\\WORK_SPACES\\CALLISTO\\DruidaDesktopV2\\userFileSystem\\usuario\\dir1\\btnDownload.gif");
		FileInputStream fileIn = new FileInputStream(fileToDownload);
		ServletOutputStream out = response.getOutputStream();
		byte[] outputByte = new byte[4096];
		//		copy binary contect to output stream
		int numBytes;
		numBytes=fileIn.read(outputByte, 0, 4096);
		while(numBytes != -1)	{
			out.write(outputByte, 0, numBytes);
			numBytes=fileIn.read(outputByte, 0, 4096);
		}
		fileIn.close();
		out.flush();
		out.close();
	}	
	
	/**
	 * Procesa download fichero.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * 
	 * @throws Exception
	 *             the exception
	 */
	public void procesaDownloadFichero (HttpServletRequest request, HttpServletResponse response) throws Exception	{
		Object oRuta=request.getParameter("path");
		Object oFile=request.getParameter("file");
		if (oRuta==null || oFile==null)	{
			ResourceBundle bundle=ResourcesService.getResourceBundle("drExplorer",request);
			throw new Exception(bundle.getString("drExplorer.txt42"));	
		}
		
		System.out.println((String)oRuta+"---"+(String)oFile);
		
		HttpSession sesion=request.getSession();
		DrExplorerService explServ=new DrExplorerService();
		File fileToDownload = explServ.getFile((String)oRuta, (String)oFile, sesion);
		//System.out.println("attachment;filename="+fileToDownload.getName());
		response.setContentType("application/octet-stream");
		response.setHeader("Content-Disposition","attachment;filename="+fileToDownload.getName());
		//File file = new File("D:\\ECLIPSE\\WORK_SPACES\\CALLISTO\\DruidaDesktopV2\\userFileSystem\\usuario\\dir1\\btnDownload.gif");
		FileInputStream fileIn = new FileInputStream(fileToDownload);
		ServletOutputStream out = response.getOutputStream();
		 
		byte[] outputByte = new byte[4096];
		//		copy binary contect to output stream
		int numBytes;
		numBytes=fileIn.read(outputByte, 0, 4096);
		while(numBytes != -1)	{
			out.write(outputByte, 0, numBytes);
			numBytes=fileIn.read(outputByte, 0, 4096);
		}
		fileIn.close();
		out.flush();
		out.close();
	}
	
	
	
	/**
	 * Gets the thumbnail.
	 * 
	 * @param image
	 *            the image
	 * @param maxThumbWidth
	 *            the max thumb width
	 * @param maxThumbHeight
	 *            the max thumb height
	 * @param hints
	 *            the hints
	 * 
	 * @return the thumbnail
	 */
	public static BufferedImage getThumbnail(BufferedImage image, int maxThumbWidth, int maxThumbHeight, RenderingHints hints){
		BufferedImage thumbnail = null;
		if(image != null) {
			AffineTransform tx = new AffineTransform();
			// Determine scale so image is not larger than the max height and/or width. 
			double scale = scaleToFit(image.getWidth(), image.getHeight(), maxThumbWidth, maxThumbHeight);
			tx.scale(scale, scale);
			double d1 = (double) image.getWidth() * scale;
			double d2 = (double) image.getHeight() * scale;
			thumbnail = new BufferedImage( 
				((int) d1) < 1 ? 1 : (int)d1,  // don't allow width to be less than 1
				((int) d2) < 1 ? 1 : (int)d2,  // don't allow height to be less than 1
				image.getType() == BufferedImage.TYPE_CUSTOM ?BufferedImage.TYPE_INT_RGB : image.getType()
			);
			Graphics2D g2d = thumbnail.createGraphics();
			g2d.setRenderingHints(hints);
			g2d.drawImage(image, tx, null);
			g2d.dispose();
		}
		return thumbnail;
	}


	/**
	 * Scale to fit.
	 * 
	 * @param w1
	 *            the w1
	 * @param h1
	 *            the h1
	 * @param w2
	 *            the w2
	 * @param h2
	 *            the h2
	 * 
	 * @return the double
	 */
	private static double scaleToFit(double w1, double h1, double w2, double h2) {
		double scale = 1.0D;
		if (w1 > h1) {
			if (w1 > w2)
				scale = w2 / w1;
			h1 *= scale;
			if (h1 > h2)
				scale *= h2 / h1;
		} else {
			if (h1 > h2)
				scale = h2 / h1;
			w1 *= scale;
			if (w1 > w2)
				scale *= w2 / w1;
		}
		return scale;
	}

	
}
